package com.flesler.stickjoy.core.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import net.java.games.input.Component;
import net.java.games.input.Controller;
import net.java.games.input.Event;
import net.java.games.input.EventQueue;
import net.java.games.input.Controller.Type;

public final class ControllerWrapper 
{
	private static byte uid = 'A';

	public static boolean isValid(Controller controller)
	{
		Type type = controller.getType();
		
		return type != Controller.Type.MOUSE 
			&& type != Controller.Type.KEYBOARD
			&& type != Controller.Type.UNKNOWN;
	}
	
	
	private Controller controller;
	private HashMap<Byte, ComponentWrapper> components;
	private byte id;
	
	public ControllerWrapper(Controller controller)
	{
		this.controller = controller;
		init();
	}
	
	private void init()
	{
		id = uid++;
		
		components = new HashMap<Byte, ComponentWrapper>();
		
		for (Component component : controller.getComponents())
		{
			ComponentWrapper wrapper = new ComponentWrapper(component);
			if (wrapper.isValid())
				components.put(wrapper.getKey(), wrapper);
			else
				wrapper.destroy();
		}
	}
	
	public byte getId()
	{
		return id;
	}
	
	public boolean poll()
	{
		return controller.poll();
	}
	
	public Collection<ComponentWrapper> getComponents()
	{
		return components.values();
	}
	
	public Collection<ComponentWrapper> getChangedComponents()
	{
		List<ComponentWrapper> list = new ArrayList<ComponentWrapper>();
		EventQueue queue = controller.getEventQueue();
		Event event = new Event();
		while (queue.getNextEvent(event)) {
			Component component = event.getComponent();
			// Find wrapper
			ComponentWrapper wrapper = components.get(ComponentWrapper.getKeyFor(component));
			
			if (wrapper == null)
				continue;
			
			// Send new value and check if changed
			if (wrapper.update(event.getValue()))
				list.add(wrapper);
		}
		return list;
	}
	
	public void destroy()
	{
		for (ComponentWrapper component : components.values())
			component.destroy();
		
		components.clear();
		components = null;
		controller = null;
	}
}
